package com.cn.steam.iam.service;

import com.cn.steam.foundation.common.model.exception.BadRequestException;
import com.cn.steam.foundation.common.model.exception.NotFoundException;
import com.cn.steam.foundation.common.utils.CryptUtils;
import com.cn.steam.foundation.common.utils.JsonUtils;
import com.cn.steam.foundation.common.utils.Op;
import com.cn.steam.iam.mapper.steam.SteamUserMapper;
import com.cn.steam.iam.model.po.ExtClientUser;
import com.cn.steam.iam.model.po.SteamUser;
import com.cn.steam.iam.model.vo.OnBehalfSslReq;
import com.cn.steam.iam.model.vo.OnBehalfSslRes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

import static com.cn.steam.foundation.common.model.CommonMessage.INVALID_PARAMETER_VALUE;

/**
 * @author: zjm
 * @create: 2021-11-20 17:59
 **/
@Service
public class IamPrivilegeService {
    public final static String STEAM_TOKEN_PREFIX = "steam_token_";
    public final static long STEAM_TOKEN_EXPIREIN = 7 * 24 * 60L;

    @Autowired
    private RedisTemplate redisTemplate;
    Logger logger = LoggerFactory.getLogger(IamPrivilegeService.class);

    @Autowired
    private ExtClientUserProfileService extClientUserProfileService;

    @Autowired
    private SteamUserMapper steamUserMapper;

    @Value("${iam.privilege.ssl.password:abcdefgabcdsteam56}")
    private String sslCodeCryptPassword;
    @Value("${iam.privilege.ssl.expirein:10}")
    private long sslCodeExpireIn;

    private static final String SSL_CODE_PREFIX = "SSL-CODE_";

    public OnBehalfSslRes generateSslCode(OnBehalfSslReq sslReq) {
        ExtClientUser clientUser = extClientUserProfileService.selectBySslUserIdAndSslType(sslReq.getSslType(),sslReq.getSslId());
        if(clientUser == null){
            throw new NotFoundException("user", sslReq.getSslId());
        }

        String originSslCode;
        do {
            originSslCode = Op.randomStr(8);
        }while (!redisTemplate.opsForValue().setIfAbsent(SSL_CODE_PREFIX + originSslCode, sslReq, sslCodeExpireIn, TimeUnit.SECONDS));

        OnBehalfSslRes res = new OnBehalfSslRes();
        res.setSslCode(CryptUtils.aesEncrypt(originSslCode, sslCodeCryptPassword));
        return res;
    }

    public OnBehalfSslRes expenseSslCode(String sslCode){
        sslCode = Op.safeTrimString(sslCode);
        String originSslCode;
        try {
            originSslCode = CryptUtils.aesDecrypt(sslCode,sslCodeCryptPassword);
        }catch (Exception e){
            throw new BadRequestException(Op.str(INVALID_PARAMETER_VALUE, "sslCode", sslCode), e);
        }
        OnBehalfSslReq req = (OnBehalfSslReq) redisTemplate.opsForValue().get(SSL_CODE_PREFIX + originSslCode);
        if (req == null) {
            throw new BadRequestException(Op.str(INVALID_PARAMETER_VALUE, "sslCode", sslCode));
        }
        OnBehalfSslRes res = new OnBehalfSslRes();
        res.setAccessToken(STEAM_TOKEN_PREFIX+ UUID.randomUUID().toString());
        loginSteamUser(res.getAccessToken(), req.getSslId());
        return res;
    }

    private void loginSteamUser(String accessToken, String sslUserId) {
        SteamUser steamUser = steamUserMapper.getUserBySslId(sslUserId);
        if (steamUser == null){
            throw new BadRequestException(Op.str(INVALID_PARAMETER_VALUE, "sslUserId", sslUserId));
        }
        redisTemplate.opsForValue()
                .set(accessToken, JsonUtils.toJsonString(steamUser), STEAM_TOKEN_EXPIREIN, TimeUnit.SECONDS);
    }

}
